#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Joy-Con双手柄检测和修复工具
"""

import pygame
import subprocess
import time
import os
import re

class JoyConDualChecker:
    def __init__(self):
        self.devices_info = {}
        
    def check_bluetooth_devices(self):
        """检查蓝牙连接的Joy-Con设备"""
        print("🔍 检查蓝牙Joy-Con设备...")
        
        try:
            # 获取已连接的蓝牙设备
            result = subprocess.run(['bluetoothctl', 'info'], 
                                  capture_output=True, text=True)
            
            # 使用hcitool检查连接状态  
            hci_result = subprocess.run(['hcitool', 'con'], 
                                      capture_output=True, text=True)
            print("蓝牙连接状态:")
            print(hci_result.stdout)
            
            # 检查Joy-Con设备
            bt_result = subprocess.run(['bluetoothctl', 'paired-devices'], 
                                     capture_output=True, text=True)
            
            left_joycon = False
            right_joycon = False
            
            for line in bt_result.stdout.split('\n'):
                if 'Joy-Con (L)' in line:
                    left_joycon = True
                    print("✅ 发现左Joy-Con配对设备")
                elif 'Joy-Con (R)' in line:  
                    right_joycon = True
                    print("✅ 发现右Joy-Con配对设备")
                    
            return left_joycon, right_joycon
            
        except Exception as e:
            print(f"❌ 检查蓝牙设备失败: {e}")
            return False, False
    
    def check_input_devices(self):
        """检查/dev/input中的设备"""
        print("\n🔍 检查输入设备...")
        
        js_devices = []
        event_devices = []
        
        try:
            # 检查js设备
            for device in os.listdir('/dev/input/'):
                if device.startswith('js'):
                    js_devices.append(device)
                elif device.startswith('event'):
                    # 检查event设备的详细信息
                    try:
                        info_result = subprocess.run(['cat', f'/sys/class/input/{device}/device/name'], 
                                                   capture_output=True, text=True)
                        if 'Nintendo' in info_result.stdout or 'Joy-Con' in info_result.stdout:
                            event_devices.append((device, info_result.stdout.strip()))
                    except:
                        pass
            
            print(f"📊 发现 {len(js_devices)} 个js设备: {js_devices}")
            print(f"📊 发现 {len(event_devices)} 个Nintendo event设备:")
            for dev, name in event_devices:
                print(f"   {dev}: {name}")
                
        except Exception as e:
            print(f"❌ 检查输入设备失败: {e}")
            
        return js_devices, event_devices
    
    def check_joycond_config(self):
        """检查joycond配置模式"""
        print("\n🔍 检查joycond配置...")
        
        try:
            # 检查joycond状态
            status_result = subprocess.run(['systemctl', 'status', 'joycond'], 
                                         capture_output=True, text=True)
            print("joycond服务状态:")
            print(status_result.stdout)
            
            # 检查joycond日志查看配置模式
            log_result = subprocess.run(['journalctl', '-u', 'joycond', '--no-pager', '-n', '20'], 
                                      capture_output=True, text=True)
            print("\njoycond最近日志:")
            print(log_result.stdout)
            
        except Exception as e:
            print(f"❌ 检查joycond配置失败: {e}")
    
    def force_separate_mode(self):
        """强制Joy-Con分离模式"""
        print("\n🔧 强制启用Joy-Con分离模式...")
        
        try:
            # 停止joycond
            print("停止joycond服务...")
            subprocess.run(['sudo', 'systemctl', 'stop', 'joycond'])
            time.sleep(2)
            
            # 断开Joy-Con连接
            print("断开Joy-Con蓝牙连接...")
            bt_devices = subprocess.run(['bluetoothctl', 'paired-devices'], 
                                      capture_output=True, text=True)
            
            for line in bt_devices.stdout.split('\n'):
                if 'Joy-Con' in line:
                    mac_match = re.search(r'([0-9A-F:]{17})', line)
                    if mac_match:
                        mac = mac_match.group(1)
                        print(f"断开设备: {mac}")
                        subprocess.run(['bluetoothctl', 'disconnect', mac])
            
            time.sleep(3)
            
            # 重启joycond  
            print("重启joycond服务...")
            subprocess.run(['sudo', 'systemctl', 'start', 'joycond'])
            time.sleep(2)
            
            return True
            
        except Exception as e:
            print(f"❌ 强制分离模式失败: {e}")
            return False
    
    def reconnect_joycons_separately(self):
        """分别重连Joy-Con"""
        print("\n🔄 分别重连Joy-Con...")
        
        print("请按照以下步骤操作:")
        print("1. 确保两个Joy-Con都已从Switch上取下")
        print("2. 按下每个Joy-Con上的小圆形同步按钮（在SR按键下方）")
        
        input("按Enter继续连接左Joy-Con...")
        
        try:
            # 进入配对模式
            print("🔵 开始配对左Joy-Con...")
            print("现在按住左Joy-Con的同步按钮，直到LED闪烁")
            
            subprocess.run(['bluetoothctl', 'scan', 'on'], timeout=5)
            time.sleep(10)
            subprocess.run(['bluetoothctl', 'scan', 'off'])
            
            input("按Enter继续连接右Joy-Con...")
            
            print("🔴 开始配对右Joy-Con...")  
            print("现在按住右Joy-Con的同步按钮，直到LED闪烁")
            
            subprocess.run(['bluetoothctl', 'scan', 'on'], timeout=5)
            time.sleep(10)
            subprocess.run(['bluetoothctl', 'scan', 'off'])
            
            print("✅ 配对完成，等待设备识别...")
            time.sleep(5)
            
        except Exception as e:
            print(f"❌ 重连失败: {e}")
    
    def test_dual_joycons(self):
        """测试双Joy-Con"""
        print("\n🎮 测试双Joy-Con设置...")
        
        pygame.init()
        pygame.joystick.init()
        
        # 刷新设备列表
        pygame.joystick.quit()
        time.sleep(1)
        pygame.joystick.init()
        
        joystick_count = pygame.joystick.get_count()
        print(f"📊 pygame检测到 {joystick_count} 个手柄设备")
        
        if joystick_count == 0:
            print("❌ 没有检测到手柄设备")
            return False
        
        joysticks = []
        for i in range(joystick_count):
            try:
                joystick = pygame.joystick.Joystick(i)
                joystick.init()
                
                name = joystick.get_name()
                print(f"✅ 手柄 {i}: {name}")
                print(f"   轴数: {joystick.get_numaxes()}")
                print(f"   按钮数: {joystick.get_numbuttons()}")
                print(f"   方向键数: {joystick.get_numhats()}")
                
                joysticks.append(joystick)
                
            except Exception as e:
                print(f"❌ 初始化手柄 {i} 失败: {e}")
        
        if len(joysticks) >= 2:
            print("✅ 成功检测到双Joy-Con!")
            return True
        elif len(joysticks) == 1:
            print("⚠️  只检测到1个设备，可能是合并模式")
            return False
        else:
            print("❌ 未正确检测到Joy-Con设备")
            return False
    
    def show_dual_joycon_guide(self):
        """显示双Joy-Con设置指南"""
        print("\n📖 双Joy-Con设置完整指南:")
        print("="*50)
        
        print("🎯 目标: 让两个Joy-Con显示为独立的js0和js1设备")
        
        print("\n📋 检查清单:")
        print("□ joycond服务运行中")
        print("□ hid-nintendo模块已加载") 
        print("□ 两个Joy-Con都已配对")
        print("□ Joy-Con处于分离模式（非合并模式）")
        
        print("\n🔧 手动修复步骤:")
        print("1. sudo systemctl stop joycond")
        print("2. bluetoothctl remove [左Joy-Con MAC]")
        print("3. bluetoothctl remove [右Joy-Con MAC]")  
        print("4. sudo systemctl start joycond")
        print("5. 分别重新配对每个Joy-Con")
        print("6. 检查: ls -la /dev/input/js*")
        
        print("\n💡 关键提示:")
        print("• 每次只配对一个Joy-Con") 
        print("• 配对时按住同步按钮直到LED快速闪烁")
        print("• 配对完成后等待3-5秒再配对下一个")
        print("• 如果仍然合并，尝试重启joycond服务")
        
        print(f"\n🔗 相关资源: [[0]](#__0) [[1]](#__1)")
    
    def run_full_diagnosis(self):
        """运行完整诊断"""
        print("🔍 Joy-Con双手柄诊断工具")
        print("="*40)
        
        # 检查蓝牙设备
        left_bt, right_bt = self.check_bluetooth_devices()
        
        # 检查输入设备  
        js_devices, event_devices = self.check_input_devices()
        
        # 检查joycond配置
        self.check_joycond_config()
        
        # 分析结果
        print("\n📊 诊断结果:")
        print(f"蓝牙设备 - 左Joy-Con: {'✅' if left_bt else '❌'}, 右Joy-Con: {'✅' if right_bt else '❌'}")
        print(f"输入设备 - js设备数量: {len(js_devices)}")
        print(f"Nintendo event设备: {len(event_devices)}")
        
        if len(js_devices) == 2:
            print("✅ 完美! 检测到两个独立的Joy-Con设备")
            return self.test_dual_joycons()
        elif len(js_devices) == 1:
            print("⚠️  只有1个js设备，但应该有2个")
            print("这可能是因为:")
            print("• Joy-Con被合并为单个控制器")
            print("• 只有一个Joy-Con正确连接")
            print("• joycond配置问题")
            
            choice = input("\n是否尝试自动修复? (y/n): ")
            if choice.lower() == 'y':
                if self.force_separate_mode():
                    self.reconnect_joycons_separately()
                    return self.test_dual_joycons()
            
        else:
            print("❌ 没有检测到Joy-Con设备")
            
        self.show_dual_joycon_guide()
        return False

def main():
    checker = JoyConDualChecker()
    success = checker.run_full_diagnosis()
    
    if success:
        print("\n🎉 双Joy-Con设置成功!")
        input("按Enter开始测试输入...")
        
        # 简单输入测试
        pygame.init()
        pygame.joystick.init()
        
        joysticks = []
        for i in range(pygame.joystick.get_count()):
            joystick = pygame.joystick.Joystick(i) 
            joystick.init()
            joysticks.append(joystick)
        
        print("🎮 双Joy-Con输入测试 (按Ctrl+C退出)")
        try:
            while True:
                pygame.event.pump()
                print("\033[2J\033[H")  # 清屏
                
                for i, joystick in enumerate(joysticks):
                    print(f"🎮 {joystick.get_name()}")
                    
                    # 检查按钮
                    buttons = []
                    for btn in range(joystick.get_numbuttons()):
                        if joystick.get_button(btn):
                            buttons.append(str(btn))
                    if buttons:
                        print(f"   按钮: {','.join(buttons)}")
                    
                    # 检查摇杆
                    axes = []  
                    for axis in range(joystick.get_numaxes()):
                        value = joystick.get_axis(axis)
                        if abs(value) > 0.1:
                            axes.append(f"{axis}:{value:.2f}")
                    if axes:
                        print(f"   摇杆: {','.join(axes)}")
                    print()
                
                time.sleep(0.1)
                
        except KeyboardInterrupt:
            print("👋 测试结束")
        finally:
            pygame.quit()
    
    else:
        print("\n❌ 双Joy-Con设置失败，请查看上述指南手动修复")

if __name__ == "__main__":
    main()
